package com.chukun.interview.feature.sealed;

import com.chukun.interview.feature.inf.base.AbstractShape;
import com.chukun.interview.feature.inf.base.PermitsRectangle;
import com.chukun.interview.feature.inf.base.PermitsSquare;
import com.chukun.interview.feature.inf.base.SealedShape;
import com.chukun.interview.feature.inf.impl.ExtendSquare;

/**
 * @author chukun
 * @version 1.0.0
 * @description java新特性: 封闭类
 *  封闭类在 JDK 17 正式发布
 *
 *  JDK 17 之前的 Java 语言，限制住可扩展性只有两个方法，
 *  使用私有类或者 final 修饰符。
 *  1、私有类不是公开接口，只能内部使用。
 *  2、final 修饰符彻底放弃了可扩展性。要么全开放，要么全封闭，可扩展性只能在可能性的两个极端游走。
 *
 *  JDK 17 之后，有了第三种方法。
 *  使用 Java 的 sealed 关键字。使用类修饰符 sealed 修饰的类是封闭类，使用类修饰符 sealed 修饰的接口是封闭接口。
 *  封闭类和封闭接口限制可以扩展或实现它们的其他类或接口。
 *
 *  怎么使用封闭类呢？
 *  封闭类这个概念，涉及到两种类型的类
 *  1、被扩展的父类，称为封闭类
 *  2、扩展而来的子类，称为许可类
 *
 *  封闭类的声明使用 sealed 类修饰符，然后在所有的 extends 和 implements 语句之后，使用 permits 指定允许扩展该封闭类的子类。
 *
 *  许可类的声明需要满足下面的三个条件
 *  1、许可类必须和封闭类处于同一模块（module）或者包空间（package）里，也就是说，在编译的时候，封闭类必须可以访问它的许可类.
 *  2、许可类必须是封闭类的直接扩展类.
 *  3、许可类必须声明是否继续保持封闭：
 *    1> 许可类可以声明为终极类（final），从而关闭扩展性.
 *    2> 许可类可以声明为封闭类（sealed），从而延续受限制的扩展性,
 *    3> 许可类可以声明为解封类（non-sealed）, 从而支持不受限制的扩展性。
 * @see SealedShape
 * @see PermitsRectangle
 * @see PermitsSquare
 *
 * @createTime 2022年06月05日 21:36:00
 */
public class SealedTemplate {
    public static void main(String[] args) {

        System.out.println(PermitsSquare.isSquare(new PermitsSquare("square", 10.0d)));

        System.out.println(PermitsSquare.isSquare(new PermitsRectangle("square", 10.0d, 10.0d)));
    }
}










